package com.ytjj.qmyx.mall.controller;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.gexin.fastjson.JSON;
import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.pagehelper.util.StringUtil;
import com.google.common.collect.Maps;
import com.huifu.adapay.core.AdapayCore;
import com.huifu.adapay.core.util.AdapaySign;
import com.kuaidi100.sdk.response.QueryTrackData;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.api.ResultCode;
import com.ytjj.common.constants.*;
import com.ytjj.common.controller.BaseController;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.exception.GlobalExceptionHandler;
import com.ytjj.common.model.UsersResponse;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.CopyWriterConfigUtil;
import com.ytjj.common.utils.SysConfigUtil;
import com.ytjj.common.utils.TokenUtil;
import com.ytjj.common.utils.feishu.FeiShuUtil;
import com.ytjj.qmyx.mall.config.CommonPropertiesConfig;
import com.ytjj.qmyx.mall.constants.IsPayConstant;
import com.ytjj.qmyx.mall.constants.WxPayConstant;
import com.ytjj.qmyx.mall.constants.WxPayTypeConstant;
import com.ytjj.qmyx.mall.mapper.*;
import com.ytjj.qmyx.mall.model.*;
import com.ytjj.qmyx.mall.model.request.*;
import com.ytjj.qmyx.mall.model.response.EvaluationProductResponse;
import com.ytjj.qmyx.mall.model.response.OrderResponse;
import com.ytjj.qmyx.mall.model.response.ProductResponse;
import com.ytjj.qmyx.mall.model.response.QualificationResponse;
import com.ytjj.qmyx.mall.service.OrdersService;
import com.ytjj.qmyx.mall.service.ProductService;
import com.ytjj.qmyx.mall.service.WxService;
import com.ytjj.qmyx.mall.service.impl.WxH5JsApiServiceImpl;
import com.ytjj.qmyx.mall.service.thirdpay.AdapayServiceImpl;
import com.ytjj.qmyx.mall.service.thirdpay.UpayService;
import com.ytjj.qmyx.mall.service.thirdpay.ZsxService;
import com.ytjj.qmyx.mall.service.thirdpay.entity.WysOrderNotify;
import com.ytjj.qmyx.mall.service.thirdpay.entity.WysReturnOrderNotify;
import com.ytjj.qmyx.mall.service.thirdpay.mhkj.MhkjService;
import com.ytjj.qmyx.mall.service.thirdpay.mhkj.utils.PayUtils;
import com.ytjj.qmyx.mall.utils.ArrayUtil;
import com.ytjj.qmyx.users.client.UsersClient;
import com.ytjj.qmyx.users.mapper.UsersInfoMapper;
import com.ytjj.qmyx.users.model.DefaultAddressDto;
import com.ytjj.qmyx.users.model.UsersDto;
import com.ytjj.qmyx.users.model.UsersInfo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;

/**
 * 订单控制器
 *
 *
 * @version 1.0
 *
 */
@RefreshScope
@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController extends BaseController {


    private final OrdersService orderService;

    private final UsersClient usersClient;

    private final RedisService redisService;

    @Resource
    private CopyWriterConfigUtil copyWriterConfigUtil;

    @Resource
    private OrdersDao ordersDao;
    @Autowired
    private ProductService productService;
    @Resource
    private UsersInfoMapper usersInfoMapper;
    @Resource
    private HelpWorkMapper helpWorkMapper;
    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private ProductSpecMapper productSpecMapper;
    @Resource
    private EvaluationProductDao evaluationProductDao;
    @Resource
    private OrdersInfoMapper ordersInfoMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private CommonPropertiesConfig commonPropertiesConfig;

    @Resource
    private SysConfigUtil sysConfigUtil;
    @Value("${seata.switch:true}")
    private Boolean seataSwitch;//seata全局事务开关
    @Value("${order.push.switch:false}")
    private Boolean orderPushSwitch;//订单实时推送开关
    //手机充值开关  1-关闭 0-开启
    @Value("${phone.recharge.switch:1}")
    private Integer phoneRechargeSwitch;
    //下单过滤开关
    @Value("${create.order.filter.switch:1}")
    private Integer createOrderFilterSiwtch;
    //黑名单token_h5
    @Value("${h5token.blacks:3f1c2a35-f4f4-7ea4-d0da-8f8c7db261a2,c6b7d2c7-2e32-82f7-747a-cab1596846b6}")
    private String h5TokenBlackList;

    @Value("${order.region:吴江区}")
    private String regionAddress;
    @Resource
    private RedissonClient redissonClient;

    //黑名单token_h5限制下单数量
    @Value("${h5token.prohibit.count:20}")
    private Integer h5TokenBlackCount;

    //限制下单地址
    @Value("${order.blackAddress:公安局,派出所,检察院,法院,工商局}")
    private String blackAddress;
    @Resource
    private UpayService upayService;
    @Resource
    private AdapayServiceImpl adapayService;

    @Resource
    private ZsxService zsxService;
    @Resource
    private MhkjService mhkjService;


    public OrderController(OrdersService orderService, UsersClient usersClient, RedisService redisService) {
        this.orderService = orderService;
        this.usersClient = usersClient;
        this.redisService = redisService;
    }

    /**
     * 校验申请0元资格
     * productId
     * @return
     */
    @PostMapping("/qualificationByActivityType")
    public CommonResult qualificationByActivityType(@RequestBody CreateOrderRequest request) {
        //1.根据商品id查询当前商品所属0元分类
        //2.根据分类校验助理次数  普通0元只能有3笔在途中的  专享只能有一次购买资格
        ProductResponse product = productService.queryProductById(request.getProductId());
        QualificationResponse response = new QualificationResponse();
        if (null == product) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.INSUFFICIENT_STOCK));
        }
        UsersResponse usersResponse = getCurrentUser();
        log.info("===usersResponse.id==={}", usersResponse.getId());
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(usersResponse.getId());
        AtomicReference<Boolean> flag = new AtomicReference<>(false);//true--说明已使用权限
        AtomicReference<Boolean> zeroFlag = new AtomicReference<>(false);//true--说明已有0助力的0元测评商品
        AtomicReference<Boolean> exclusiveIngFlag = new AtomicReference<>(false);//true--说明已有专属商品助力
        AtomicReference<Boolean> exclusiveOverFlag = new AtomicReference<>(false);//true--说明已有专属商品助力

        //判断用户是否使用掉
        if (null != usersInfo.getIsQuality() && usersInfo.getIsQuality().equals(1)){
            HelpWorkExample helpWorkExample = new HelpWorkExample();
            helpWorkExample.createCriteria().andUserIdEqualTo(usersResponse.getId());
            //查一下是否用了严选官的权限---可以助力购买一次专属商品或者不助力购买一次0元测评商品
            List<HelpWork> helpWorks = helpWorkMapper.selectByExample(helpWorkExample);
            helpWorks.stream().forEach(item ->{
                //
                if (item.getHelpNum().equals(0)){
                    zeroFlag.set(true);
                    flag.set(true);
                }
                EvaluationProductResponse productResp = evaluationProductDao.findByProductId(item.getProductId());
                if (null != productResp && null != productResp.getAppraisalType() && productResp.getAppraisalType().equals(2) && !item.getStatus().equals(2)) {
                    if (item.getStatus().equals(1)){
                        exclusiveIngFlag.set(true);
                        flag.set(true);
                    }
                    if (item.getStatus().equals(3)){
                        exclusiveOverFlag.set(true);
                        flag.set(true);
                    }
                }
            });
            response.setFlag(flag.get());
            if (null == product.getAppraisalType() || product.getAppraisalType().equals(1)) {
                long normalNum = orderService.helpWorkNum(usersResponse.getId());
                if (normalNum >= 3) {
                    response.setStatus(1);
                    response.setFlag(flag.get());
                    return CommonResult.success(response);//有三件0元测评的商品正在助力
                }
            }
            if (zeroFlag.get()){
                response.setStatus(3);
                return CommonResult.success(response);//已有0助力的0元测评商品
            }
            if (exclusiveIngFlag.get()){
                response.setStatus(4);
                return CommonResult.success(response);//已有专属商品助力进行中
            }
            if (exclusiveOverFlag.get()){
                response.setStatus(5);
                return CommonResult.success(response);//已有专属商品助力已完成
            }
        }else {
            if (null == product.getAppraisalType() || product.getAppraisalType().equals(1)) {
                long normalNum = orderService.helpWorkNum(usersResponse.getId());
                if (normalNum >= 3) {
                    response.setStatus(1);
                    response.setFlag(flag.get());
                    return CommonResult.success(response);//有三件0元测评的商品正在助力
                }
            }
            response.setStatus(2);
            response.setFlag(flag.get());
            return CommonResult.success(response);//普通用户没有三件0元测评的商品正在助力
        }

//        //判断该商品是0元还是专属商品
//        ProductResponse product = productService.queryProductById(request.getProductId());
//        if (null == product) {
//            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.INSUFFICIENT_STOCK));
//        }
//        if ("ZERO_EVALUATION".equals(product.getActivityType())) {
//            if (null == product.getAppraisalType() || product.getAppraisalType().equals(1)) {
//                long normalNum = orderService.helpWorkNum(usersResponse.getId());
//                if (normalNum >= 3) {
//                    return CommonResult.success(1);
//                    //throw new ApiException("您还有3个试用在进行中，请先完成 ！");
//                }
//            }else {
//                int zhuanshuNum = orderService.selectOrdersZhuanShu(usersResponse.getId());
//                if (zhuanshuNum >= 1) {
//                    return CommonResult.success(2);
//                    //throw new ApiException("您之前领取过专属试用品哦！");
//                }
//            }
//        }
        response.setStatus(0);
        response.setFlag(flag.get());
        return CommonResult.success(response);//查询不到状态
    }



    /**
     * 创建订单
     *
     * @param request
     * @return
     */
//    @PostMapping("/createOrder")
//    public CommonResult createOrder(@RequestBody CreateOrderRequest request) {
//        log.info("====createOrder==={}", request);
//        UsersResponse usersResponse = getCurrentUser();
//        request.setOrderSource(getSource());
//        log.info(TokenUtil.getRequest().getHeader("channel"));
//        request.setChannel(StringUtils.isEmpty(TokenUtil.getChannel()) ? usersResponse.getChannel() : TokenUtil.getChannel());
//        request.setUserId(usersResponse.getId());
//        request.setTel(usersResponse.getTel());
//        request.setOpenid(usersResponse.getOpenid());
//        request.setHeadImg(usersResponse.getHeadImg());
//        request.setNickName(usersResponse.getNickname());
//        if (!StringUtils.isEmpty(request.getCartNoStr())) {
//            String[] cartNos = request.getCartNoStr().split(",");
//            request.setCartNo(cartNos);
//        }
//        String h5_token = TokenUtil.getToken();
//        //黑名单限制
//        String prohibitUserTel = redisService.get(RedisConstants.PROHIBIT_USER_TEL_KEY);
//        if (!StringUtils.isEmpty(prohibitUserTel)) {
//            List<String> ids = Arrays.asList(prohibitUserTel.split(","));
//            if (!CollectionUtils.isEmpty(ids) && ids.contains(request.getTel())) {
//                throw new ApiException("下单失败！");
//            }
//        }
//        Integer noPayCount = orderService.queryNoPayAndNoCancelCount(h5_token);
//        if (Optional.ofNullable(noPayCount).isPresent() && noPayCount >= h5TokenBlackCount) {
//            throw new ApiException("下单失败！");
//        }
//
//        return CommonResult.success(orderService.createOrder(request));
//    }

    /**
     * 小程序创建订单
     * @param request
     * @return
     */
    @PostMapping("/createOrderV2")
    public CommonResult createOrderV2(@RequestBody CreateOrderRequest request) {
        log.info("====createOrder==={}", request);
        UsersResponse usersResponse = getCurrentUser();
        if (usersResponse==null || usersResponse.getId() == null){
            throw new ApiException(ResultCode.UNAUTHORIZED);
        }
        request.setOrderSource(getSource());
        log.info(TokenUtil.getRequest().getHeader("channel"));
        request.setChannel(StringUtils.isEmpty(TokenUtil.getChannel()) ? usersResponse.getChannel() : TokenUtil.getChannel());
        request.setUserId(usersResponse.getId());
        request.setTel(usersResponse.getTel());
        request.setOpenid(usersResponse.getOpenid());
        request.setHeadImg(usersResponse.getHeadImg());
        request.setNickName(usersResponse.getNickname());
        if (!StringUtils.isEmpty(request.getCartNoStr())) {
            String[] cartNos = request.getCartNoStr().split(",");
            request.setCartNo(cartNos);
        }
        String childId = super.getChildId();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(childId)){
            if ("0".equals(childId)){
                request.setAccount("");
            }
        }
        String h5_token = TokenUtil.getToken();
        //黑名单限制
        String prohibitUserTel = redisService.get(RedisConstants.BLACK_USER_TEL_KEY+request.getTel());
        if (org.apache.commons.lang3.StringUtils.isNotBlank(prohibitUserTel)){
            throw new ApiException("下单失败,-2");
        }
        //下单次数限制
        Integer noPayCount = orderService.queryNoPayAndNoCancelCount(h5_token);
        if (Optional.ofNullable(noPayCount).isPresent() && noPayCount >= h5TokenBlackCount) {
            throw new ApiException("下单失败,-1");
        }
        request.setChildId(getChildId());
        Integer orderId = orderService.createOrder(request);
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        Map<String,String> response = new HashMap<>();
        response.put("orderId",orders.getId().toString());
        response.put("orderNo",orders.getOrderNo());
        return CommonResult.success(response);
    }

    @PostMapping("/cartCreateOrder")
    public CommonResult cartCreateOrder(@RequestBody CreateOrderRequest request) {
        log.info("====cartCreateOrder==={}", request);
        UsersResponse usersResponse = getCurrentUser();
        request.setOrderSource(getSource());
        log.info(TokenUtil.getRequest().getHeader("channel"));
        request.setChannel(StringUtils.isEmpty(TokenUtil.getChannel()) ? usersResponse.getChannel() : TokenUtil.getChannel());
        request.setUserId(usersResponse.getId());
        request.setTel(usersResponse.getTel());
        request.setOpenid(usersResponse.getOpenid());
        request.setHeadImg(usersResponse.getHeadImg());
        request.setNickName(usersResponse.getNickname());
        if (!StringUtils.isEmpty(request.getCartNoStr())) {
            String[] cartNos = request.getCartNoStr().split(",");
            request.setCartNo(cartNos);
        }
        return CommonResult.success(orderService.cartCreateOrder(request));
    }

    /**
     * 填写地址
     *
     * @param request
     * @return
     */
    @PostMapping("/writeOrderAddress")
    public CommonResult writeOrderAddress(@RequestBody WriteOrderAddressRequest request){
        String effectAoId = getEffectAoId();
        request.setA_oId(effectAoId);
        orderService.writeOrderAddress(request);
        return CommonResult.success(ResultCode.SUCCESS);
    }

    @PostMapping("/writeOrderAddressV2")
    public CommonResult writeOrderAddressV2(@RequestBody WriteOrderAddressRequest request){
        orderService.writeOrderAddressV2(request);
        return CommonResult.success(ResultCode.SUCCESS);
    }

    /**
     * 获取订单详情信息
     *
     * @return
     */
//    @GetMapping("/queryOrderInfoById")
//    public CommonResult queryOrderInfoById(@RequestParam("orderInfoId") Integer orderInfoId) {
//        return CommonResult.success(orderService.queryOrderInfoById(orderInfoId,getSource(),this.getH5CurrentUser()));
//    }

    /**
     * 获取订单详情信息
     *
     * @return
     */
    @GetMapping("/queryOrderInfoByChildOrderNo")
    public CommonResult queryOrderInfoByChildOrderNo(@RequestParam("childOrderNo") String childOrderNo) {
        return CommonResult.success(orderService.queryOrderInfoByChildOrderNo(childOrderNo, getSource(), this.getH5CurrentUser()));
    }

//    /**
//     * 根据订单详情id获取物流（作废接口）
//     *
//     * @return
//     */
//    @GetMapping("/getLogisticsInfo")
//    public CommonResult getLogisticsInfo(@RequestParam(value = "orderInfoId",required = false) Integer orderInfoId){
//        List<QueryTrackData> queryTrackData = orderService.getLogisticsInfo(orderInfoId);
//        return CommonResult.success(queryTrackData);
//    }

    /**
     * 确认收货（目前H5没开放此接口）
     *
     * @return
     */
    @GetMapping("/receivingGoods")
    public CommonResult receivingGoods(@RequestParam("orderInfoId") Integer orderInfoId){
        orderService.receivingGoods(orderInfoId);
        return CommonResult.success(ResultCode.SUCCESS);
    }

    /**
     * 获取订单支付信息
     *
     * @return
     */
//    @GetMapping("/getOrderInfoById")
//    public CommonResult getOrderInfoById(@RequestParam("orderId") Integer orderId,String city) {
//        return CommonResult.success(orderService.getOrderInfoById(orderId, getCurrentUser().getId(),city));
//    }

    @GetMapping("/getOrderInfoByNo")
    public CommonResult getOrderInfoByNo(@RequestParam("orderNo") String orderNo,String city) {
        return CommonResult.success(orderService.getOrderInfoByNo(orderNo, getCurrentUser().getId(),city));
    }


//    /**
//     * 获取运费
//     *
//     * @return
//     */
//    @GetMapping("/getCalculateFreight")
//    public CommonResult getCalculateFreight(Integer orderId, String city) {
//        BigDecimal total = orderService.getCalculateFreight(orderId,city);
//        Map<String,BigDecimal> data = Maps.newHashMap();
//        data.put("freight",total);
//        return CommonResult.success(data);
//    }

    /**
     * 积分支付方式 (h5/app)
     * @return
     */
    @GetMapping("/cashScorePay")
    public CommonResult cashScorePay() {
        return CommonResult.success(sysConfigUtil.getSysConfig(SysConfigConstants.CASH_SCORE_PAY_TIP));
    }

    /**
     * 获取订单信息
     *
     * @return
     */
//    @GetMapping("/getPaySuccessInfo")
//    public CommonResult getPaySuccessInfo(@RequestParam("orderId") Integer orderId,Integer payOrderId) {
//        UsersResponse usersResponse = getH5CurrentUser();
//        if(getSource().equals("h5") && payOrderId!=null){
//            OrderResponse paySuccessInfo = orderService.getPaySuccessInfo(orderId, usersResponse, payOrderId);
//            paySuccessInfo.setScore(getH5CurrentUser().getScore());
//            return CommonResult.success(paySuccessInfo);
//        }
//        OrderResponse paySuccessInfo = orderService.getPaySuccessInfo(orderId, usersResponse,null);
//        paySuccessInfo.setScore(getH5CurrentUser().getScore());
//        return CommonResult.success(paySuccessInfo);
//    }

    /**
     * 根据主订单号查询订单信息
     * @param orderNo
     * @param payOrderId
     * @return
     */
    @GetMapping("/getPaySuccessInfoByOrderNo")
    public CommonResult getPaySuccessInfoByOrderNo(@RequestParam("orderNo") String orderNo,Integer payOrderId) {
        UsersResponse usersResponse = getH5CurrentUser();
        if(getSource().equals("h5")){
            OrderResponse paySuccessInfo = orderService.getPaySuccessInfoByOrderNo(orderNo, usersResponse,payOrderId);
            paySuccessInfo.setScore(getH5CurrentUser().getScore());
            return CommonResult.success(paySuccessInfo);
        }
        OrderResponse paySuccessInfo = orderService.getPaySuccessInfoByOrderNo(orderNo, usersResponse,payOrderId);
        paySuccessInfo.setScore(getH5CurrentUser().getScore());
        return CommonResult.success(paySuccessInfo);
    }

    /**
     * 支付成功页面领取红包
     *
     * @return
     */
    @GetMapping("/receiveReward")
    public CommonResult receiveReward(@RequestParam("orderId") Integer orderId) {
        orderService.receiveReward(orderId, getCurrentUser().getId());
        return CommonResult.success(ResultCode.SUCCESS);
    }

    /**
     * 编辑订单的地址、电话、姓名
     *
     * @return
     */
    @PostMapping("/updateOrdersUserInfo")
    public CommonResult updateOrdersUserInfo(@RequestBody OrdersUserInfoRequest ordersUserInfoRequest) {
        orderService.updateOrdersUserInfo(ordersUserInfoRequest);
        return CommonResult.success(ResultCode.SUCCESS);
    }

    /**
     * 重新购买
     *
     * @param orderId
     * @return
     */
    @GetMapping("/anewBuy")
    public CommonResult anewBuy(@RequestParam("orderId") Integer orderId){
        UsersResponse usersResponse = getCurrentUser();
        return CommonResult.success(orderService.anewBuy(orderId, usersResponse.getId(),usersResponse.getChannel()));
    }

    /**
     * 判断严选官是否领取专享试用
     * @return
     */
    @GetMapping("/selectOrdersZhuanShu")
    public CommonResult selectOrdersZhuanShu() {
        UsersResponse usersResponse = getCurrentUser();
        return CommonResult.success(orderService.selectOrdersZhuanShu(usersResponse.getId()));
    }


    /**
     * 货到付款 支付
     * @param request
     * @return
     */
    @PostMapping("cashOnDelivery")
    public CommonResult cashOnDelivery(@RequestBody UnifiedOrderRequest request){
        orderService.cashOnDelivery(request);
        return CommonResult.success();
    }


    /**
     * h5微信支付生产预付款订单（话费充值）
     * @return
     */
    @PostMapping("/h5WxDoUnifiedPhoneOrder")
    public CommonResult h5WxDoUnifiedPhoneOrder(@RequestBody UnifiedOrderPhoneRequest request){
        if (phoneRechargeSwitch.equals(1)) {
            return CommonResult.failed("充值维护中，请逛逛其它商品吧！");
        }
        UsersResponse usersResponse = getH5CurrentUser();
        return CommonResult.success(orderService.h5WxDoUnifiedPhoneOrder(request,usersResponse));
    }

    /**
     * 微信H5支付异步回调(话费充值)
     * 调用下面的统一回调接口了wxNotifyV3
     * @param request
     * @return
     */
    @PostMapping("/wxH5PhonePayNotify")
    public String wxH5PhonePayNotify(HttpServletRequest request) {
        try {
            String result = orderService.wxH5PhonePayBack(this.getWxRes(request));
            return result;
        } catch (Exception e) {
            log.info("微信H5支付失败:" + e.getMessage());
            String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            return result;
        }
    }

    /**
     * h5微信查询（话费充值）
     * @return
     */
    @GetMapping("/phoneBillComplete")
    public CommonResult phoneBillComplete(@RequestParam("orderId") Integer orderId){
        return CommonResult.success(orderService.phoneBillComplete(orderId));
    }


    @GetMapping("/rechargeUpdate")
    public CommonResult rechargeUpdate () {
        orderService.rechargeUpdate();
        return CommonResult.success();
    }

    /**
     * 获取微信响应
     * @param request
     * @return
     * @throws IOException
     */
    private String getWxRes(HttpServletRequest request) throws IOException {
        String resXml = "";
        InputStream inputStream = request.getInputStream();
        //将InputStream转换成xmlString
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        resXml = sb.toString();
        log.info(resXml);
        return resXml;
    }

    /**
     * 更新订单支付
     *
     * @param map
     */
    @PostMapping("/updateOrdersPay")
    public void updateOrdersPay(@RequestBody Map<String, String> map) {
        log.info("更新订单支付 {}",JSONObject.toJSONString(map));
        String tradeType=map.get("trade_type")+"";
        if(WxPayConstant.ISV_TRADE_TYPE_H5.equalsIgnoreCase(tradeType)) {
            orderService.updateH5OrderPay(map);
        }else {
            orderService.updateOrderPay(map);
        }
    }

    /**
     * 更新支付宝订单支付
     *
     * @param response
     */
    @PostMapping("/updateAliPayOrdersPay")
    void updateAliPayOrdersPay(@RequestBody AlipayTradeQueryResponse response) {
        orderService.updateAliPayOrdersPay(response);
    }

    /**
     * 获取订单列表
     *
     * @param ordersRequest
     * @return
     */
    @PostMapping("/getOrdersList")
    public CommonResult getOrdersList(@RequestBody QueryOrdersRequest ordersRequest) {
        Integer userId = this.getCurrentUser().getId();
        log.info("currentUserId={}", userId);
        if (null == userId) {
            return CommonResult.success();
        }
        ordersRequest.setUserId(userId);
        return CommonResult.success(orderService.getOrdersList(ordersRequest));
    }

    /**
     * ----------------用户手动取消订单-----------------
     *
     * @param orderNo
     * @return
     */
    @GetMapping("/cancelOrder")
    public CommonResult cancelOrder(@RequestParam String orderNo){
        return orderService.cancelOrder(orderNo);
    }


    /**
     * ----------------用户手动删除订单-----------------
     * @param orderInfoId
     * @return
     */
    @GetMapping("/deleteOrder")
    public CommonResult deleteOrder(@RequestParam("orderInfoId") Integer orderInfoId) {
        return orderService.deleteOrder(orderInfoId);
    }

    /**
     * 获取H5订单列表
     * @param ordersRequest
     * @return
     */
    @PostMapping("/getH5OrdersList")
    public CommonResult getH5OrdersList(@RequestBody QueryOrdersRequest ordersRequest) {
        if (getH5CurrentUser()==null){
            return CommonResult.success();
        }
        log.info(getH5CurrentUser().getToken());
        log.info(TokenUtil.getToken());
        log.info("当前的visitorId=================================="+TokenUtil.getVisitorId());
        ordersRequest.setH5Token(getH5CurrentUser().getToken());
        return CommonResult.success(orderService.getH5OrdersList(ordersRequest));
    }

    /**
     * 根据手机号环境订单列表
     *
     * @param ordersRequest
     * @return
     */
//    @PostMapping("/getOrdersListByTel")
//    public CommonResult getOrdersListByTel(@RequestBody QueryOrdersRequest ordersRequest){
//        return CommonResult.success(orderService.getOrdersListByTel(ordersRequest));
//    }

    /**
     * 获取积分订单列表
     *
     * @return
     */
    @GetMapping("/getScoreOrderList")
    public CommonResult getScoreOrderList() {
        UsersResponse user = getCurrentUser();
        return CommonResult.success(orderService.getScoreOrderInfoList(user.getId()));
    }

    /**
     * 获取积分订单列表
     *
     * @return
     */
    @GetMapping("/getH5ScoreOrderList")
    public CommonResult getH5ScoreOrderList() {
        UsersResponse user = getH5CurrentUser();
        return CommonResult.success(orderService.getScoreOrderInfoList(user.getToken()));
    }

    /**
     * 获取新品试用订单列表
     *
     * @return
     */
    @GetMapping("/getNewProOrderList")
    public CommonResult getNewProOrderList() {
        UsersResponse user = getCurrentUser();
        return CommonResult.success(orderService.getNewProOrderInfoList(user.getId()));
    }

    /**
     * 获取可发布订单列表
     *
     * @param request
     * @return
     */
    @PostMapping("/getDynamicOrdersList")
    public CommonResult getDynamicOrdersList(@RequestBody PageRequest request){
        return CommonResult.success(orderService.getDynamicOrderList(getCurrentUser().getId(),request.getPageNum(),request.getPageSize()));
    }

    /**
     * 我的已购清单
     *
     * @param request
     * @return
     */
    @PostMapping("/getMyOrdersList")
    public CommonResult getMyOrdersList(@RequestBody PageRequest request){
        return CommonResult.success(orderService.getDynamicOrderListV2(getCurrentUser().getId(),request.getPageNum(),request.getPageSize()));
    }


    /**
     * 获取他的已购清单
     */
    @PostMapping("/getOtherOrdersList")
    public CommonResult getOtherOrdersList(@RequestBody OrderRequest orderRequest) {
        return CommonResult.success(orderService.getDynamicOrderListV2(orderRequest.getUserId(), orderRequest.getPageNum(), orderRequest.getPageSize()));
    }




    /**
     * 物流查询
     *
     * @param orderInfoId
     * @return
     */
    @GetMapping("/checkLogistics")
    public CommonResult checkLogistics(@RequestParam("orderInfoId") Integer orderInfoId) {
        UsersResponse currentUser = this.getH5CurrentUser();
        return CommonResult.success(orderService.checkLogistics(orderInfoId, currentUser));
    }

    /**
     * h5 创建订单
     *
     * @param request
     * @return
     */
//    @PostMapping("/h5CreateOrder")
//    public CommonResult h5CreateOrder(@RequestBody H5CreateOrderRequest request){
//        request.setOrderSource(getSource());
//        log.info(TokenUtil.getRequest().getHeader("channel"));
//        log.info("===h5CreateOrder==={}", request);
//        request.setChannel(TokenUtil.getRequest().getHeader("channel") == null?"":TokenUtil.getRequest().getHeader("channel"));
//        request.setDomainUrl(TokenUtil.getRequest().getHeader("domainUrl"));
//        String h5_token = TokenUtil.getToken();
//        if (1 == createOrderFilterSiwtch && !StringUtils.isEmpty(h5TokenBlackList)) {
//            log.info("====h5_token==={}", h5_token);
//            String[] h5TokenBlackLists = h5TokenBlackList.split(",");
//            List<String> h5Tokens = Arrays.asList(h5TokenBlackLists);
//            if (h5Tokens.contains(h5_token)) {
//                log.info("===h5 token is enter black list==={}", h5_token);
//                throw new ApiException("订单创建失败！");
//            }
//        }
//        String effectAoId = getEffectAoId();
//        request.setA_oId(effectAoId);
//        //黑名单限制
//        String prohibitUserTel = redisService.get(RedisConstants.PROHIBIT_USER_TEL_KEY);
//        if (!StringUtils.isEmpty(prohibitUserTel)) {
//            List<String> ids = Arrays.asList(prohibitUserTel.split(","));
//            if (!CollectionUtils.isEmpty(ids) && ids.contains(request.getTel())) {
//                throw new ApiException("下单失败！");
//            }
//        }
//        Integer noPayCount = orderService.queryNoPayAndNoCancelCount(h5_token);
//        if (Optional.ofNullable(noPayCount).isPresent() && noPayCount >= h5TokenBlackCount) {
//            throw new ApiException("下单失败！");
//        }
//
//        Integer orderId = orderService.h5CreateOrder(request);
//        return CommonResult.success(orderId);
//    }

    /**
     * h5 创建订单（新接口）
     * @param request
     * @return
     */
    @PostMapping("/h5CreateOrderV2")
    public CommonResult h5CreateOrderV2(@RequestBody H5CreateOrderRequest request){
        if(request.getMark() != null && 1 == request.getMark()){
            request.setOrderSource(SalesChannelConstants.AREA_PLATFORM_PRE);
        }else {
            request.setOrderSource(getSource());
        }
        log.info(TokenUtil.getRequest().getHeader("channel"));
        log.info("===h5CreateOrder==={}", request);
        request.setChannel(TokenUtil.getRequest().getHeader("channel") == null?"":TokenUtil.getRequest().getHeader("channel"));
        request.setDomainUrl(TokenUtil.getRequest().getHeader("domainUrl"));
        String h5_token = TokenUtil.getToken();
        if (1 == createOrderFilterSiwtch && !StringUtils.isEmpty(h5TokenBlackList)) {
            log.info("====h5_token==={}", h5_token);
            String[] h5TokenBlackLists = h5TokenBlackList.split(",");
            List<String> h5Tokens = Arrays.asList(h5TokenBlackLists);
            if (h5Tokens.contains(h5_token)) {
                log.info("===h5 token is enter black list==={}", h5_token);
                throw new ApiException("订单创建失败！");
            }
        }
        //黑名单限制
        String prohibitUserTel = redisService.get(RedisConstants.BLACK_USER_TEL_KEY+request.getTel());
        if (org.apache.commons.lang3.StringUtils.isNotBlank(prohibitUserTel)){
            throw new ApiException("下单失败,-2");
        }
        //下单次数限制
        Integer noPayCount = orderService.queryNoPayAndNoCancelCount(h5_token);
        if (Optional.ofNullable(noPayCount).isPresent() && noPayCount >= h5TokenBlackCount) {
            throw new ApiException("下单失败,-1");
        }
        //敏感地址限制
        if (org.apache.commons.lang3.StringUtils.isNotBlank(request.getAddress()) && blackAddress!=null){
            String[] blackAddressList = blackAddress.split(",");
            for (String bd : blackAddressList) {
                if (request.getAddress().contains(bd)){
                    throw new ApiException("该地区不可下单,-3");
                }
            }
        }


        Integer orderId = orderService.h5CreateOrder(request);
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        Map<String,String> response = new HashMap<>();
        response.put("orderId",orders.getId().toString());
        response.put("orderNo",orders.getOrderNo());
        return CommonResult.success(response);
    }

    /**
     * 修改订单 领取红包
     * @return
     */
    @GetMapping("/updateOrderRedpacket")
    public CommonResult updateOrderRedpacket(String orderNo){
        return CommonResult.success(orderService.updateOrderRedpacket(orderNo));
    }

    /**
     * h5 购物车创建订单
     *
     * @param request
     * @return
     */
    @PostMapping("/h5CartCreateOrder")
    public CommonResult h5CartCreateOrder(@RequestBody H5CartCreateOrderRequest request){
        request.setOrderSource(getSource());
        log.info(TokenUtil.getRequest().getHeader("channel"));
        log.info("===h5CartCreateOrder==={}", request);
        request.setChannel(TokenUtil.getRequest().getHeader("channel") == null?"":TokenUtil.getRequest().getHeader("channel"));
        Integer orderId = orderService.h5CartCreateOrder(request);
        return CommonResult.success(orderId);
    }

    /**
     * 获取订单信息
     *
     * @return
     */
//    @GetMapping("/getH5OrderInfoById")
//    public CommonResult getH5OrderInfoById(@RequestParam(value = "orderId") Integer orderId) {
//        UsersResponse h5CurrentUser = getH5CurrentUser();
//        return CommonResult.success(orderService.getH5OrderInfoById(orderId, h5CurrentUser));
//    }

    /**
     * 获取订单信息
     *
     * @return
     */
    @GetMapping("/getH5OrderInfoByOrderNo")
    public CommonResult getH5OrderInfoByOrderNo(@RequestParam(value = "orderNo") String orderNo) {
        UsersResponse h5CurrentUser = getH5CurrentUser();
        return CommonResult.success(orderService.getH5OrderInfoByOrderNo(orderNo, h5CurrentUser));
    }

    /**
     * 获取H5订单支付状态
     *
     * @param
     * @return
     */
//    @GetMapping("/getH5OrdersPayStatus")
//    public CommonResult getH5OrdersPayStatus(@RequestParam("orderId") Integer orderId,
//                                             @RequestParam("payOrderId") Integer payOrderId){
//        return CommonResult.success(orderService.getH5OrdersPayStatus(orderId,payOrderId));
//    }



    @GetMapping("/getPayConfigByCompany")
    public PayConfigDto getPayConfigByCompany(@RequestParam("company") String company){
        PayConfigDto payConfigDto = new PayConfigDto();
        log.info("getPayConfigByCompany:company={},TYPE={},TRADE_TYPE={}",company,WxH5JsApiServiceImpl.TYPE,WxH5JsApiServiceImpl.TRADE_TYPE);
        PayConfig payConfig = ordersDao.getPayConfigByCompany(company, WxH5JsApiServiceImpl.TYPE,WxH5JsApiServiceImpl.TRADE_TYPE);
        log.info("getPayConfigByCompany:payConfig{}",payConfig);
        BeanUtils.copyProperties(payConfig,payConfigDto);
        log.info("getPayConfigByCompany:payConfigDto{}",payConfigDto);
        return payConfigDto;
    }

    @Autowired
    private Map<String,WxService> wxServiceMap;

    /**
     * 微信订单查询
     * @param resOrderNo
     * @param tradeType
     * @return
     */
    @GetMapping("/wxAppOrderQuery")
    public Map<String, String> wxOrderQuery(@RequestParam("resOrderNo") String resOrderNo,
                                             @RequestParam("tradeType") String tradeType){
        try {
            log.info("===tradeType==={},{}", resOrderNo, tradeType);
            if("MWEB".equals(tradeType) || "ISV-MWEB".equals(tradeType) || "JSAPI".equals(tradeType) || "JSAPI2".equals(tradeType)){
                return wxServiceMap.get("H5-"+tradeType).wxOrderQuery(resOrderNo);
            }
            return wxServiceMap.get("APP-"+tradeType).wxOrderQuery(resOrderNo);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("发起查询发生异常：e:{}",GlobalExceptionHandler.getExceptionToString(e));
        }
        throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.QUERY_FAILED));
    }

//    /**
////     * 申请交易账单
////     * @return
////     */
////    @GetMapping("/getTradebill")
////    public CommonResult getTradebill() {
////        try {
////            log.info("===getTradebill start===");
////            String response = orderService.tradebillByWx();
////            return CommonResult.success(response);
////        } catch (Exception e) {
////            log.error("===getTradebill is err==={}", e);
////        }
////        return CommonResult.failed();
////    }

//    @GetMapping("/downloadBill")
//    public CommonResult downloadBill(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
//        try {
//            log.info("===downloadBill start===");
//            orderService.downloadBill(servletResponse);
//            return CommonResult.success();
//        } catch (Exception e) {
//            log.error("===downloadBill is err==={}", e);
//        }
//        return CommonResult.failed();
//    }

    /**
     * 解析对账单
     */
    public void parseTradeBill() {
        LocalDate ld = LocalDate.now(ZoneId.systemDefault());
        ld = ld.plusDays(-1);
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String dateStr = ld.format(fmt);

        String fileName = dateStr + ".zip";
        File file = new File("/mnt/tradebill/" + fileName);
    }

    /**
     * 微信订单退款
     *
     * @param tradeType
     * @param tradeNo
     * @param refundNo
     * @param totalFee
     * @param refundFee
     * @param desc
     * @return
     */
    @GetMapping("/refundOrders")
    public Map<String, String> refundOrders(@RequestParam("tradeType")String tradeType,
                                            @RequestParam("tradeNo")String tradeNo,
                                            @RequestParam("refundNo")String refundNo,
                                            @RequestParam("totalFee")Integer totalFee,
                                            @RequestParam("refundFee")Integer refundFee,
                                            @RequestParam("desc")String desc){
        try {
            log.info("refundOrders:tradeType:{},tradeNo={},refundNo={}",tradeType,tradeNo,refundNo);
            if("MWEB".equals(tradeType) || "MWEB2".equals(tradeType)){
                return wxServiceMap.get("H5-"+tradeType).refundOrders(tradeNo,refundNo,totalFee,refundFee,desc);
            }

            return wxServiceMap.get("APP-"+tradeType).refundOrders(tradeNo,refundNo,totalFee,refundFee,desc);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("发起退款发生异常：e:{}",GlobalExceptionHandler.getExceptionToString(e));
            HashMap<String, String> map = Maps.newHashMap();
            map.put("return_code","FAIL");
            map.put("return_msg",e.getMessage());
            return map;
        }
    }

    /**
     * 微信订单退款
     *
     * @param tradeType
     * @param tradeNo
     * @param refundNo
     * @param totalFee
     * @param refundFee
     * @param desc
     * @return
     */
    @GetMapping("/h5RefundOrders")
    public Map<String, String> h5RefundOrders(@RequestParam("tradeType")String tradeType,
                                            @RequestParam("tradeNo")String tradeNo,
                                            @RequestParam("refundNo")String refundNo,
                                            @RequestParam("totalFee")Integer totalFee,
                                            @RequestParam("refundFee")Integer refundFee,
                                            @RequestParam("desc")String desc){
        try {
            log.info("h5RefundOrders:tradeType:{},tradeNo={},refundNo={}",tradeType,tradeNo,refundNo);
            if("H5-JSAPI".equals(tradeType) || "H5-JSAPI2".equals(tradeType) || "H5-MWEB".equals(tradeType) || "H5-MWEB2".equals(tradeType)){
                return wxServiceMap.get(tradeType).refundOrders(tradeNo,refundNo,totalFee,refundFee,desc);
            }
            return wxServiceMap.get("H5-"+tradeType).refundOrders(tradeNo,refundNo,totalFee,refundFee,desc);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("发起退款发生异常h5RefundOrders：e:{}",GlobalExceptionHandler.getExceptionToString(e));
            HashMap<String, String> map = Maps.newHashMap();
            map.put("return_code","FAIL");
            map.put("return_msg",e.getMessage());
        }
        throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.REFUND_FAILED));
    }

    /**
     * 查看该手机号是否支付过订单
     * @param tel
     * @return
     */
    @GetMapping("/queryCountByTel")
    public Integer queryCountByTel(@RequestParam(value = "tel",required = false) String tel){
        if (!StringUtils.isEmpty(tel)){
            Integer count = ordersDao.queryCountByTel(tel);
            return count;
        }
        return 0;
    }

    /**
     * 查看该手机号是否支付过订单
     * @param tel
     * @return
     */
    @GetMapping("/queryCountByTelRpc")
    public DynamicDto queryCountByTelRpc(@RequestParam(value = "tel" , required = false) String tel){
        Integer count = 0;
        if (!StringUtils.isEmpty(tel)){
            count = ordersDao.queryCountByTel(tel);
        }
        DynamicDto dto = new DynamicDto();
        dto.setNum(count);
        return dto;
    }

    @PostMapping("/appRecharge")
    public CommonResult appRecharge(@RequestBody UnifiedOrderPhoneRequest request) {
        return CommonResult.success(orderService.appRecharge(request, null));
    }



    /**
     * 微信APP 充值支付异步回调
     *
     * @param request
     * @return
     */
    @PostMapping("/wxAppRechargePayNotify")
    public String wxAppRechargePayNotify(HttpServletRequest request) {
        try {
            String result = orderService.wxAppRechargePayBack(this.getWxRes(request));
            return result;
        } catch (Exception e) {
            log.info("微信手机支付失败:" + e.getMessage());
            String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            return result;
        }
    }

    @PostMapping("/wxAppletRechargePayNotify")
    public String wxAppletRechargePayNotify(HttpServletRequest request) {
        try {
            String result = orderService.wxAppletRechargePayBack(this.getWxRes(request));
            return result;
        } catch (Exception e) {
            log.info("微信手机支付失败:" + e.getMessage());
            String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            return result;
        }
    }



    /**
     * 微信app支付生成预付款订单
     *
     * @param request
     * @return
     */
    @PostMapping("/wxDoUnifiedOrder")
    public CommonResult wxDoUnifiedOrder(@RequestBody UnifiedOrderRequest request) {
        String h5_token = TokenUtil.getToken();
        if (1 == createOrderFilterSiwtch && !StringUtils.isEmpty(h5TokenBlackList)) {
            log.info("====h5_token==={}", h5_token);
            String[] h5TokenBlackLists = h5TokenBlackList.split(",");
            List<String> h5Tokens = Arrays.asList(h5TokenBlackLists);
            if (h5Tokens.contains(h5_token)) {
                log.info("===token is enter black list==={}", h5_token);
                throw new ApiException("-1006");
            }
        }
        log.info("微信app支付生成预付款订单参数:{}",JSONObject.toJSONString(request));
        UsersResponse usersResponse = getCurrentUser();
        if(request.getAddressId() == null){
            return CommonResult.failed("收货地址未填写");
        }
        log.info("微信app支付生成预付款订单参数usersResponse:{}",JSONObject.toJSONString(usersResponse));
        DefaultAddressDto oneAddress = usersClient.getAddressByUserIdOrId(usersResponse.getId(), request.getAddressId());

        String city = oneAddress.getCity();
        if (city.equals("市辖区")){
            city = oneAddress.getProvince();
        }
        String province = oneAddress.getProvince();

        //敏感地址限制
        if (org.apache.commons.lang3.StringUtils.isNotBlank(oneAddress.getAddress()) && blackAddress!=null){
            String[] blackAddressList = blackAddress.split(",");
            for (String bd : blackAddressList) {
                if (oneAddress.getAddress().contains(bd)){
                    throw new ApiException("该地区不可下单,-3");
                }
            }
        }

        //校验商品上下架/库存/收货地址
        if (null != request.getOrderId()){
            OrdersInfoExample ordersInfoExample = new OrdersInfoExample();
            ordersInfoExample.createCriteria().andOrderIdEqualTo(request.getOrderId());
            List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectByExample(ordersInfoExample);
            String finalCity = city;
            log.info("==========finalCity========{}",finalCity);

            ordersInfoList.stream().forEach(ordersInfo -> {
                boolean b = orderService.checkProductStock(ordersInfo.getProductId(), ordersInfo.getProductSpecId(), ordersInfo.getProductSum());
                if (!b){
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.INSUFFICIENT_STOCK));
                }
                //获取运费模板
                FreightTemplateResponse freightTemplateResponse = orderService.getFreightTemplateResponse(ordersInfo.getProductId());
                if (null != freightTemplateResponse) {
                    //判断是否在限制地区
                    YxAstrictRegionResponse astrictRegion = freightTemplateResponse.getAstrictRegion();
                    if (ObjectUtil.isNotNull(astrictRegion) && org.apache.commons.lang3.StringUtils.isNotBlank(astrictRegion.getRegionDesc())) {
                        String[] region = astrictRegion.getRegionDesc().split(",");
                        Optional<String> regionFlag = Stream.of(region).filter(x -> x.contains(province)).findFirst();
                        if (regionFlag.isPresent() && regionFlag.get().contains("全境")) {
                            throw new ApiException("您所在的区域该商品不能下单，先去看看其他商品吧~");
                        }
                    }
                    if (null != astrictRegion && org.apache.commons.lang3.StringUtils.isNotBlank(astrictRegion.getRegion())) {
                        String[] region = astrictRegion.getRegion().split(",");
//                        region = ArrayUtil.add(region, regionAddress);
                        Optional<String> regionFlag = Stream.of(region).filter(x -> x.equals(finalCity)).findFirst();
                        Optional<String> areaRegionFlag = Stream.of(region).filter(x -> x.equals(oneAddress.getArea())).findFirst();
                        if (regionFlag.isPresent() && org.apache.commons.lang3.StringUtils.isNotBlank(regionFlag.get())) {
                            throw new ApiException("您所在的区域该商品不能下单，先去看看其他商品吧~");
                        }
                        if ( areaRegionFlag.isPresent() && org.apache.commons.lang3.StringUtils.isNotBlank(areaRegionFlag.get())) {
                            throw new ApiException("您所在的区域该商品不能下单，先去看看其他商品吧~");
                        }
                    }
                }
            });
        }
        String type = request.getType();
        if(WxPayTypeConstant.JSAPI.equals(type)){
            if(StringUtil.isEmpty(request.getOpenid())){
                request.setOpenid(usersResponse.getOpenid());
            }else{
                usersClient.saveOpenId(usersResponse.getId(),request.getOpenid());
                redisService.set(TokenUtil.getToken(), JSONObject.toJSONString(usersResponse));
                redisService.expire(TokenUtil.getToken(), TokenConstants.EXPIRE_SECONDS);
            }
        }
        log.info("用户id：{}",usersResponse.getId());
        UsersDto usersDto = usersClient.getUsersInfo(usersResponse.getId());
        request.setScore(usersDto.getScore());

        request.setSourcePlatform(usersResponse.getSource());
        //判断能否余额支付，能就走余额支付
//        boolean checkBalancePay = checkBalancePay(request);
//        if (checkBalancePay) {
//            Map map = orderService.balancePayByOrder(request);
//            //用户支付成功 发送消息给队列 调用同步到供应商的方法
//            try {
//                orderService.subStock(request.getOrderId());
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//            if (orderPushSwitch) {
//                try {
//                    log.info("上传供应链1============{}",request.getOrderId());
//                    orderService.ordersUpload(request.getOrderId(),null);
//                } catch (Exception e) {
//                    log.error("上传供应链1============{},{}",request.getOrderId(),e);
//                }
//            }
//            return CommonResult.success(map);
//        }
        Map map = orderService.wxDoUnifiedOrder(request);
        //用户支付成功 发送消息给队列 调用同步到供应商的方法
//        try {
//            orderService.subStock(request.getOrderId());
//            if (orderPushSwitch) {
//                log.info("上传供应链2============{}",request.getOrderId());
//                orderService.ordersUpload(request.getOrderId(),null);
//            }
//        } catch (Exception e) {
//            log.error("上传供应链2失败============{},{}",request.getOrderId(),e);
//        }
        orderService.checkPaymentChannelStatus("wx");
        return CommonResult.success(map);
    }

    @PostMapping("/wxDoUnifiedOrderV2")
    public CommonResult wxDoUnifiedOrderV2(@RequestBody UnifiedOrderRequest request) {
        Assert.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(request.getOrderNo()),"订单号不能为空");
        Assert.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(request.getOpenid()),"openid不能为空");
        Assert.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(request.getType()),"type不能为空");

        Map map = orderService.wxDoUnifiedOrderV2(request);
        String domainUrl = TokenUtil.getDomainUrl();
        orderService.checkPaymentChannelStatus("wx",domainUrl);
        return CommonResult.success(map);
    }

    @PostMapping("/wxDoUnifiedOrderV2Zfb")
    public CommonResult wxDoUnifiedOrderV2Zfb(@RequestBody UnifiedOrderRequest request) {
        Assert.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(request.getOrderNo()),"订单号不能为空");
        Assert.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(request.getType()),"type不能为空");


        Map map = orderService.wxDoUnifiedOrderV2(request);
        if ("UPAY".equals(request.getType())){
            orderService.checkPaymentChannelStatus("upay");
        }
        if ("HFTX".equals(request.getType())){
            orderService.checkPaymentChannelStatus("hftx");
        }
        if ("ZSY".equals(request.getType())){
            String domainUrl = TokenUtil.getDomainUrl();
            orderService.checkPaymentChannelStatus("zsy",domainUrl);
        }
        return CommonResult.success(map);
    }

    /**
     * 判断能否余额支付
     * @param request
     * @return
     */
    public boolean checkBalancePay(UnifiedOrderRequest request) {
        if (!seataSwitch) {
            return false;
        }
        Orders orders = orderService.getById(request.getOrderId());
        if (null == orders) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ORDER_NON_EXISTENT));
        }
        if (IsPayConstant.YES.equals(orders.getIsPay())) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.PAID));
        }
        DefaultAddressDto address = usersClient.getOneAddress(orders.getUserId(), request.getAddressId());
        if (address == null) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ADDRESS_NONEXISTENT));
        }
        if(null != request.getIsUseMoneyDeduction() && request.getIsUseMoneyDeduction()) {
            BigDecimal money = usersClient.getMoney(orders.getUserId());
            if (money != null && orders.getRealTotalMoney().compareTo(money) < 1) {
                return true;
            }
            if(money != null && orders.getRealTotalMoney().doubleValue() > 0d && money.doubleValue() > 0d) {
                return true;
            }
        }
        return false;
    }


    /**
     * h5微信支付生产预付款订单
     * @param request
     * @return
     */
    @PostMapping("/h5WxDoUnifiedOrder")
    public CommonResult h5WxDoUnifiedOrder(@RequestBody UnifiedOrderRequest request){
        UsersResponse usersResponse = getH5CurrentUser();
        String h5_token = TokenUtil.getToken();
        if (1 == createOrderFilterSiwtch && !StringUtils.isEmpty(h5TokenBlackList)) {
            log.info("====h5_token==={}", h5_token);
            String[] h5TokenBlackLists = h5TokenBlackList.split(",");
            List<String> h5Tokens = Arrays.asList(h5TokenBlackLists);
            if (h5Tokens.contains(h5_token)) {
                log.info("===h5 token is enter black list==={}", h5_token);
                throw new ApiException("-1005");
            }
        }
        log.info("h5WxDoUnifiedOrder===request={}====usersResponse={}",JSONObject.toJSONString(request),JSONObject.toJSONString(usersResponse));
//        RLock lock = redissonClient.getLock("mall:h5WxDoUnifiedOrder:" + request.getOrderId());
//        lock.lock();
        try {
            orderService.checkPaymentChannelStatus("wx");
            return CommonResult.success(orderService.h5WxDoUnifiedOrder(request,usersResponse));
        } catch (Exception e) {
            return CommonResult.failed(e.getMessage());
        }finally {
//            lock.unlock();
        }
    }


    /**
     * 微信APP支付异步回调
     *
     * @param request
     * @return
     */
    @PostMapping("/wxAppPayNotify")
    public String wxAppPayNotify(HttpServletRequest request) {
        try {
            String result = orderService.wxAppPayBack(this.getWxRes(request));
            return result;
        } catch (Exception e) {
            log.info("微信手机支付失败:" + e.getMessage());
            String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            return result;
        }
    }


    /**
     * 微信小程序支付异步回调
     *
     * @param request
     * @returng
     */
    @PostMapping("/wxAppletPayNotify")
    public String wxAppletPayNotify(HttpServletRequest request) {
        try {
            String result = orderService.wxAppletPayBack(this.getWxRes(request),"APP","JSAPI");
            return result;
        } catch (Exception e) {
            log.info("微信小程序支付失败:" + e.getMessage());
            String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            return result;
        }
    }

    /**
     * JSAPI V2支付回调
     * @param request
     * @return
     */
    @PostMapping("/wxAppletPayNotifyJSAPI")
    public String wxAppletPayNotifyJSAPI(HttpServletRequest request) {
        try {
            String result = orderService.wxAppletPayBack(this.getWxRes(request),"H5","JSAPI");
            return result;
        } catch (Exception e) {
            log.info("JSAPI V2支付失败:" + e.getMessage());
            String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            return result;
        }
    }

    /**
     * upay支付回调通知
     * @param req
     * @return
     */
    @PostMapping("/wxNotifyUpay")
    public void wxNotifyUpay(HttpServletRequest req){
        log.info("wxNotifyUpay");
        upayService.notifyUpay(req);
    }

    /**
     * 智收银异步回调通知
     */
    @PostMapping(value="/notifyZSY",consumes = "application/x-www-form-urlencoded")
    public String notifyZSY(@ModelAttribute WysOrderNotify wxPayNotify){
        try {
            log.info("notifyZSY入参,{}", com.alibaba.fastjson.JSON.toJSONString(wxPayNotify));
            zsxService.notifyZSY(wxPayNotify);
            return "success ";
        } catch (Exception e) {
           log.error("notifyZSY失败,{}",e);
        }
        return "faile";
    }

    /**
     * 米花科技支付回调
     * @param request
     * @param httpServletResponse
     * @return
     */
    @GetMapping("/notifyMhkj")
    public String notifyMhkj(HttpServletRequest request , HttpServletResponse httpServletResponse){
        return mhkjService.notifyuMhkj(request);
    }

    /**
     * 米花科技退款回调
     * @param request
     * @param httpServletResponse
     * @return
     */
    @GetMapping("/notifyuMhkjRefund")
    public String notifyuMhkjRefund(HttpServletRequest request , HttpServletResponse httpServletResponse){
        return mhkjService.notifyuMhkjRefund(request);
    }

    /**
     *  智收银退款异步回调通知
     * @param wysReturnOrderNotify
     * @return
     */
    @PostMapping(value="/notifyReturnZSY",consumes = "application/x-www-form-urlencoded")
    public String notifyReturnZSY(@ModelAttribute WysReturnOrderNotify wysReturnOrderNotify){
        try {
            log.info("notifyReturnZSY入参,{}", com.alibaba.fastjson.JSON.toJSONString(wysReturnOrderNotify));
            zsxService.notifyZsyRefund(wysReturnOrderNotify);
            return "success ";
        } catch (Exception e) {
            log.error("notifyReturnZSY,{}",e);
        }
        return "faile";
    }

    /**
     * Adapay支付回调通知
     * @param request
     */
    @PostMapping("/notifyAdapay")
    public void notifyAdapay(HttpServletRequest request) {
        try {
            //验签请参data
            String data = request.getParameter("data");
            //验签请参sign
            String sign = request.getParameter("sign");
            //验签标记
            boolean checkSign;
            //验签请参publicKey
            String publicKey = AdapayCore.PUBLIC_KEY;
            log.info("验签请参：data={}sign={}",data,sign);
            //验签
            checkSign = AdapaySign.verifySign(data, sign, publicKey);
            if(checkSign){
                //验签成功逻辑
                log.info("成功返回数据data:"+data);
                String type = request.getParameter("type");
                //支付回调
                if ("payment.succeeded".equals(type) || "payment.failed".equals(type)){
                    adapayService.notifyAdapay(data);
                }
                //退款回调
                if ("refund.succeeded".equals(type) || "refund.failed".equals(type)){
                    adapayService.notifyAdapayRefund(data);
                }
            }else {
                //验签失败逻辑
            }
        }catch (Exception e){
            log.info("Adapay支付回调通知报错,{}",e);
            FeiShuUtil.sendMsg(String.format("Adapay支付回调通知报错,%s",e.getMessage()));
        }
    }

    /**
     * upay退回调通知
     * @param req
     */
    @PostMapping("/notifyUpayRefund")
    public void notifyUpayRefund(HttpServletRequest req){
        log.info("notifyUpayRefund");
        upayService.notifyUpayRefund(req);
    }

    /**
     * 首信易退款
     * @param transactionId
     * @param refundNo
     * @param amount
     * @return
     */
    @GetMapping("/upayRefund")
    public int upayRefund(String transactionId,String refundNo,String amount){
        Assert.notNull(transactionId, "transactionId不能为空");
        Assert.notNull(refundNo, "refundNo不能为空");
        Assert.notNull(amount, "amount不能为空");
        log.info("/order/upayRefund参数,{},{},{}",transactionId,refundNo,amount);
        return upayService.refund(transactionId, refundNo, amount);
    }

    /**
     * 智收营退款
     * @param mchOrderNo
     * @param refundNo
     * @param amount
     * @return
     */
    @GetMapping("/zsyRefund")
    public int zsyRefund(String mchOrderNo,String refundNo,String amount,String payTime){
        Assert.notNull(mchOrderNo, "mchOrderNo不能为空");
        Assert.notNull(refundNo, "refundNo不能为空");
        Assert.notNull(amount, "amount不能为空");
        log.info("/order/zsyRefund,{},{},{}",mchOrderNo,refundNo,amount);
        return zsxService.zsyRefund(mchOrderNo,refundNo,amount,payTime);
    }

    /**
     * 退差价退款
     * @param mchOrderNo
     * @param refundNo
     * @param amount
     * @return
     */
    @GetMapping("/zsyRefundCJ")
    public int zsyRefundCJ(String mchOrderNo,String refundNo,String amount,String payTime){
        Assert.notNull(mchOrderNo, "mchOrderNo不能为空");
        Assert.notNull(refundNo, "refundNo不能为空");
        Assert.notNull(amount, "amount不能为空");
        log.info("/order/zsyRefund,{},{},{}",mchOrderNo,refundNo,amount);
        return zsxService.zsyRefundCJ(mchOrderNo,refundNo,amount,payTime);
    }

    /**
     * 米花科技退款
     * @param mchOrderNo
     * @param refundNo
     * @param amount
     * @param payTime
     * @return
     */
    @GetMapping("/mhkjRefund")
    public String mhkjRefund(String mchOrderNo,String refundNo,String amount,String payTime){
        Assert.notNull(mchOrderNo, "mchOrderNo不能为空");
        Assert.notNull(refundNo, "refundNo不能为空");
        Assert.notNull(amount, "amount不能为空");
        log.info("/order/mhkjRefund,{},{},{}",mchOrderNo,refundNo,amount);
        return mhkjService.mhkjRefund(mchOrderNo,refundNo,amount,payTime);
    }

    @GetMapping("/mhkjRefundCj")
    public String mhkjRefundCj(String mchOrderNo,String refundNo,String amount,String payTime){
        Assert.notNull(mchOrderNo, "mchOrderNo不能为空");
        Assert.notNull(refundNo, "refundNo不能为空");
        Assert.notNull(amount, "amount不能为空");
        log.info("/order/mhkjRefundCj,{},{},{}",mchOrderNo,refundNo,amount);
        return mhkjService.mhkjRefundCj(mchOrderNo,refundNo,amount,payTime);
    }

    /**
     * 微信H5支付异步回调
     *
     * @param request
     * @return
     */
    @PostMapping("/wxH5PayNotify")
    public String wxH5PayNotify(HttpServletRequest request) {
        try {
            String result = orderService.wxH5PayBack(this.getWxRes(request));
            return result;
        } catch (Exception e) {
            log.info("微信H5支付失败:" + e.getMessage());
            String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            return result;
        }
    }

    /**
     * 微信支付V3回调通知处理
     * @param request
     * @param type
     * @param data
     * @return
     * @throws WxPayException
     */
    @PostMapping("/wxNotifyV3/{type}")
    public String wxNotifyV3(HttpServletRequest request,@PathVariable String type,@RequestBody String data) throws WxPayException {
        log.info("收到微信支付回调通知，type={},data={}",type,data);
        String nonce = request.getHeader("Wechatpay-Nonce");
        String signature = request.getHeader("Wechatpay-Signature");
        String timestamp = request.getHeader("Wechatpay-Timestamp");
        String serial = request.getHeader("Wechatpay-Serial");
        SignatureHeader signatureHeader=new SignatureHeader();
        signatureHeader.setNonce(nonce);
        signatureHeader.setSignature(signature);
        signatureHeader.setTimeStamp(timestamp);
        signatureHeader.setSerial(serial);
        return orderService.wxV3PayBack(type,data,signatureHeader);
    }

    /**
     * h5的Adapay 小程序支付回调通知处理
     * @param request
     * @param type 类型
     * @return
     * @throws WxPayException
     */
    @PostMapping("/adapayPayNotify/{type}")
    public String AdapayPayNotify(HttpServletRequest request,@PathVariable String type){
        return orderService.adapayPayNotify(request,type);
    }

    /**
     * 微信退款V3回调通知处理
     * @param request
     * @param type 支付类型
     * @param data
     * @return
     * @throws WxPayException
     */
    @PostMapping("/wxRefundNotifyV3/{type}")
    public String wxRefundNotifyV3(HttpServletRequest request, @PathVariable String type, @RequestBody String data) throws WxPayException {
        log.info("收到微信退款回调通知，type={},data={}",type,data);
        String nonce = request.getHeader("Wechatpay-Nonce");
        String signature = request.getHeader("Wechatpay-Signature");
        String timestamp = request.getHeader("Wechatpay-Timestamp");
        String serial = request.getHeader("Wechatpay-Serial");
        log.info("=====nonce:{}", nonce);
        log.info("=====signature:{}", signature);
        log.info("=====timestamp:{}", timestamp);
        log.info("=====serial:{}", serial);
        SignatureHeader signatureHeader=new SignatureHeader();
        signatureHeader.setNonce(nonce);
        signatureHeader.setSignature(signature);
        signatureHeader.setTimeStamp(timestamp);
        signatureHeader.setSerial(serial);
        log.info("=========wxRefundNotifyV3,signatureHeader:{}", JSON.toJSONString(signatureHeader));
        return orderService.wxV3RefundBack(type,data,signatureHeader);
        //后续改成调用wxPayV3NotifyByISVSUB
    }

    /**
     * 轮询查小程序支付状态
     * @param orderId 订单Id
     * @return CommonResult
     */
    @GetMapping("/checkWxMiniPayStatus")
    public CommonResult checkWxMiniPayStatus(Integer orderId){
        return orderService.checkWxMiniPayStatus(orderId);
    }

    @GetMapping("/ceshi")
    public CommonResult test(@RequestParam Integer productId){
//        orderService.calculateFreight(productId,1,"南京市");
        return CommonResult.success();
    }

    @GetMapping("/ordersUpload")
    public CommonResult ordersUpload(@RequestParam Integer orderId){
        try {
            orderService.ordersUpload(orderId,null);
        } catch (Exception e) {
            log.error("订单推送到供应链失败,orderId:{},错误:{}",orderId,e);
            FeiShuUtil.sendMsg(String.format("订单推送到供应链失败,orderId:%s,错误:%s",orderId,e.getMessage()));
        }
        return CommonResult.success();
    }


    @GetMapping("/toTransferOrders")
    public CommonResult toTransferOrders(@RequestParam("orderId") Integer orderId,@RequestParam("transferId") Integer transferId){
        try {
            orderService.ordersUpload(orderId,transferId);
        } catch (Exception e) {
            log.error("订单转单并推送到供应链失败,orderId:{},错误:{}",orderId,e);
            FeiShuUtil.sendMsg(String.format("订单转单并推送到供应链失败,orderId:%s,错误:%s",orderId,e.getMessage()));
        }
        return CommonResult.success();
    }


    /**
     * 修改订单地址
     * @param childOrderNo
     * @param tel
     * @param address
     * @return
     */
    @GetMapping("/updateOrderAddress")
    public CommonResult updateOrderAddress(String childOrderNo,String tel,String address,String newTel,String userName){
        try {
            Assert.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(childOrderNo),"订单号不能为空");
            Assert.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(tel),"原手机号不能为空");
            Assert.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(newTel),"新手机号不能为空");
            Assert.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(address),"地址不能为空");
            Assert.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(userName),"收货人不能为空");
            orderService.updateOrderAddress(childOrderNo, tel, address,newTel,userName);
            return CommonResult.success("修改成功");
        } catch (Exception e) {
            return CommonResult.failed(e.getMessage());
        }
    }
}
